<!doctype html><html lang=cn-zh><head><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="IE=edge"><style type=text/css>body{font-family:monospace}</style><title>[python]ImportError:attempted relative import with no known parent package</title>
<meta name=description content="A blog maintained by Vimiix."><link rel=stylesheet href=/css/style.css><script>var _hmt=_hmt||[];(function(){var e,t=document.createElement("script");t.src="https://hm.baidu.com/hm.js?7c24231917964240bae97e813810620c",e=document.getElementsByTagName("script")[0],e.parentNode.insertBefore(t,e)})()</script></head><body><header>====================<br>== Hi, I'm Vimiix ==<br>====================<div style=float:right;color:gray;font-size:x-large>Get hands dirty.</div><br><p><nav><a href=https://www.vimiix.com/><b>首页</b></a>.
<a href=/posts/><b>文章列表</b></a>.
<a href=/projects/><b>开源项目</b></a>.
<a href=/tags/><b>标签</b></a>.
<a href=/friends/><b>友链</b></a>.
<a href=/about/><b>关于我</b></a>.
<a href=/index.xml><b>RSS</b></a>.</nav></p></header><main><article><h1>[python]ImportError:attempted relative import with no known parent package</h1><b><time>2017.12.29 12:37</time></b>
<a href=/tags/python>Python</a>
<a href=/tags/%E7%BF%BB%E8%AF%91>翻译</a>
<a href=/tags/importerror>importError</a><div><h2 id=前言>前言</h2><p>在这篇文章中，我将会解析 <code>ImportError: attempted relative import with no known parent package</code> 这个异常的原因。当你在运行的 python 脚本。使用了相对引用方式 <em>(类似<code>import ..module</code>)</em> 去引用包时，可能会出现这个异常。</p><p>让我们来看看发生这个异常的例子。</p><h2 id=问题>问题</h2><p>假设你有以下目录结构：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>project
</span></span><span style=display:flex><span>├── config.py
</span></span><span style=display:flex><span>└── package
</span></span><span style=display:flex><span>    ├── __init__.py
</span></span><span style=display:flex><span>    └── demo.py
</span></span></code></pre></div><p><code>config.py</code> 中包含一些应该在 <code>demo.py</code> 中使用的变量</p><ul><li>project/config.py</li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>count <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span></code></pre></div><ul><li>project/package/demo.py</li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span><span style=color:#f92672>from</span> .. <span style=color:#f92672>import</span> config
</span></span><span style=display:flex><span>print(<span style=color:#e6db74>&#34;The value of config.count is </span><span style=color:#e6db74>{0}</span><span style=color:#e6db74>&#34;</span><span style=color:#f92672>.</span>format(config<span style=color:#f92672>.</span>count))
</span></span></code></pre></div><p>当我们尝试运行<code>demo.py</code>时，会遇到以下错误：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>E:\project<span style=color:#f92672>&gt;</span> python demos<span style=color:#f92672>/</span>demo<span style=color:#f92672>.</span>py
</span></span><span style=display:flex><span>Traceback (most recent call last):
</span></span><span style=display:flex><span>  File <span style=color:#e6db74>&#34;demos/demo.py&#34;</span>, line <span style=color:#ae81ff>1</span>, <span style=color:#f92672>in</span> <span style=color:#f92672>&lt;</span>module<span style=color:#f92672>&gt;</span>
</span></span><span style=display:flex><span>    <span style=color:#f92672>from</span> .. <span style=color:#f92672>import</span> config
</span></span><span style=display:flex><span><span style=color:#a6e22e>ImportError</span>: attempted relative <span style=color:#f92672>import</span> with no known parent package
</span></span></code></pre></div><p>python 解释器抛出了没有父级包的异常。为什么？</p><p>让我们看看 python 解释器是如何解析相关模块。从 <a href=https://www.python.org/dev/peps/pep-0328/>PEP 328</a> 中，我们找到了关于 <code>the relative imports</code>（相对引用）的介绍：</p><blockquote><p>Relative imports use a module’s <strong>__name__</strong> attribute to determine that module’s position in the package hierarchy. If the module’s name does not contain any package information (e.g. it is set to <strong>__main__</strong> ) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.</p><p>相对导入通过使用模块的 <strong>__name__</strong> 属性来确定模块在包层次结构中的位置。如果该模块的名称不包含任何包信息（例如，它被设置为 <strong>__main__</strong> ），那么相对引用会认为这个模块就是顶级模块，而不管模块在文件系统上的实际位置。</p></blockquote><p>换句话说，解决模块的算法是基于<code>__name__</code>和<code>__package__</code>变量的值。大部分时候，这些变量不包含任何包信息 &mdash;- 比如：当 <code>__name__</code> = <code>__main__</code> 和 <code>__package__</code> = <code>None</code> 时，python 解释器不知道模块所属的包。在这种情况下，相对引用会认为这个模块就是顶级模块，而不管模块在文件系统上的实际位置。</p><p>为了演示这个原理，我们来更新一下代码：</p><ul><li>project/config.py</li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>print(<span style=color:#e6db74>&#39;__file__=</span><span style=color:#e6db74>{0:&lt;35}</span><span style=color:#e6db74> | __name__=</span><span style=color:#e6db74>{1:&lt;20}</span><span style=color:#e6db74> | __package__=</span><span style=color:#e6db74>{2:&lt;20}</span><span style=color:#e6db74>&#39;</span><span style=color:#f92672>.</span>format(__file__,__name__,str(__package__)))
</span></span><span style=display:flex><span>count <span style=color:#f92672>=</span> <span style=color:#ae81ff>5</span>
</span></span></code></pre></div><ul><li>project/package/demo.py</li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>print(<span style=color:#e6db74>&#39;__file__=</span><span style=color:#e6db74>{0:&lt;35}</span><span style=color:#e6db74> | __name__=</span><span style=color:#e6db74>{1:&lt;20}</span><span style=color:#e6db74> | __package__=</span><span style=color:#e6db74>{2:&lt;20}</span><span style=color:#e6db74>&#39;</span><span style=color:#f92672>.</span>format(__file__,__name__,str(__package__)))
</span></span><span style=display:flex><span><span style=color:#f92672>from</span> .. <span style=color:#f92672>import</span> config
</span></span><span style=display:flex><span>print(<span style=color:#e6db74>&#34;The value of config.count is </span><span style=color:#e6db74>{0}</span><span style=color:#e6db74>&#34;</span><span style=color:#f92672>.</span>format(config<span style=color:#f92672>.</span>count))
</span></span></code></pre></div><p>再次尝试运行一下，会得到以下输出：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>E:\project<span style=color:#f92672>&gt;</span> python demos<span style=color:#f92672>/</span>demo<span style=color:#f92672>.</span>py
</span></span><span style=display:flex><span>__file__<span style=color:#f92672>=</span>demos<span style=color:#f92672>/</span>demo<span style=color:#f92672>.</span>py      <span style=color:#f92672>|</span> __name__<span style=color:#f92672>=</span>__main__    <span style=color:#f92672>|</span> __package__<span style=color:#f92672>=</span><span style=color:#66d9ef>None</span>
</span></span><span style=display:flex><span>Traceback (most recent call last):
</span></span><span style=display:flex><span>  File <span style=color:#e6db74>&#34;demos/demo.py&#34;</span>, line <span style=color:#ae81ff>3</span>, <span style=color:#f92672>in</span> <span style=color:#f92672>&lt;</span>module<span style=color:#f92672>&gt;</span>
</span></span><span style=display:flex><span>    <span style=color:#f92672>from</span> .. <span style=color:#f92672>import</span> config
</span></span><span style=display:flex><span><span style=color:#a6e22e>ImportError</span>: attempted relative <span style=color:#f92672>import</span> with no known parent package
</span></span></code></pre></div><p>正如我们所看到的，python 解释器没有关于模块所属的包的任何信息（ <code>__name__</code> = <code>__main__</code> 和 <code>__package__</code> = <code>None</code> ），因此它抛出了找不到父级包的异常。</p><h2 id=解决方案一>解决方案一</h2><ul><li><p>我们通过在其中创建一个新的空 <code>__init__.py</code> 文件来将项目目录转换为一个包。</p></li><li><p>我们在项目目录的父目录中创建一个文件 <code>main.py</code></p></li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>toplevel
</span></span><span style=display:flex><span>├── main.py
</span></span><span style=display:flex><span>└── project
</span></span><span style=display:flex><span>  ├── __init__.py
</span></span><span style=display:flex><span>  ├── config.py
</span></span><span style=display:flex><span>  └── package
</span></span><span style=display:flex><span>      ├── __init__.py
</span></span><span style=display:flex><span>      └── demo.py
</span></span></code></pre></div><ul><li>toplevel/main.py</li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>print(<span style=color:#e6db74>&#39;__file__=</span><span style=color:#e6db74>{0:&lt;35}</span><span style=color:#e6db74> | __name__=</span><span style=color:#e6db74>{1:&lt;20}</span><span style=color:#e6db74> | __package__=</span><span style=color:#e6db74>{2:&lt;20}</span><span style=color:#e6db74>&#39;</span><span style=color:#f92672>.</span>format(__file__,__name__,str(__package__)))
</span></span><span style=display:flex><span><span style=color:#f92672>import</span> project.demos.demo
</span></span></code></pre></div><p>执行一下新的示例，输出如下：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>E:\toplevel<span style=color:#f92672>&gt;</span>python main<span style=color:#f92672>.</span>py
</span></span><span style=display:flex><span>__file__<span style=color:#f92672>=</span>main<span style=color:#f92672>.</span>py                             <span style=color:#f92672>|</span> __name__<span style=color:#f92672>=</span>__main__             <span style=color:#f92672>|</span> __package__<span style=color:#f92672>=</span><span style=color:#66d9ef>None</span>
</span></span><span style=display:flex><span>__file__<span style=color:#f92672>=</span>E:\toplevel\project\demos\demo<span style=color:#f92672>.</span>py   <span style=color:#f92672>|</span> __name__<span style=color:#f92672>=</span>project<span style=color:#f92672>.</span>demos<span style=color:#f92672>.</span>demo   <span style=color:#f92672>|</span> __package__<span style=color:#f92672>=</span>project<span style=color:#f92672>.</span>demos
</span></span><span style=display:flex><span>__file__<span style=color:#f92672>=</span>E:\toplevel\project\config<span style=color:#f92672>.</span>py       <span style=color:#f92672>|</span> __name__<span style=color:#f92672>=</span>project<span style=color:#f92672>.</span>config       <span style=color:#f92672>|</span> __package__<span style=color:#f92672>=</span>project
</span></span><span style=display:flex><span>The value of config<span style=color:#f92672>.</span>count <span style=color:#f92672>is</span> <span style=color:#ae81ff>5</span>
</span></span></code></pre></div><p>在 <code>main.py</code> 中导入 <code>project.demos.demo</code> 会设置相对引用的包信息（ <code>__name__</code> 和 <code>__package__</code> 变量）。现在，python 解释器可以成功解析 <code>project\demos\demo.py</code> 中的相对引用了。</p><h2 id=解决方案二>解决方案二</h2><ul><li><p>我们通过在 <code>project</code> 文件夹中创建一个新的空 <code>__init__.py</code> 来将 <code>project</code> 目录转换为一个包。</p></li><li><p>在 <code>toplevel</code> 目录下通过 <code>-m</code> 参数来调用 python 解释器，去执行 <code>project.demos.demo</code><a href=#note1>[1]</a></p></li></ul><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-shell data-lang=shell><span style=display:flex><span>toplevel
</span></span><span style=display:flex><span>└── project
</span></span><span style=display:flex><span>  ├── __init__.py
</span></span><span style=display:flex><span>  ├── config.py
</span></span><span style=display:flex><span>  └── package
</span></span><span style=display:flex><span>      ├── __init__.py
</span></span><span style=display:flex><span>      └── demo.py
</span></span></code></pre></div><p>再次执行：</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span>E:\toplevel<span style=color:#f92672>&gt;</span>python <span style=color:#f92672>-</span>m project<span style=color:#f92672>.</span>demos<span style=color:#f92672>.</span>demo
</span></span><span style=display:flex><span>__file__<span style=color:#f92672>=</span>E:\toplevel\project\demos\demo<span style=color:#f92672>.</span>py   <span style=color:#f92672>|</span> __name__<span style=color:#f92672>=</span>__main__        <span style=color:#f92672>|</span> __package__<span style=color:#f92672>=</span>project<span style=color:#f92672>.</span>demos
</span></span><span style=display:flex><span>__file__<span style=color:#f92672>=</span>E:\toplevel\project\config<span style=color:#f92672>.</span>py       <span style=color:#f92672>|</span> __name__<span style=color:#f92672>=</span>project<span style=color:#f92672>.</span>config  <span style=color:#f92672>|</span> __package__<span style=color:#f92672>=</span>project
</span></span><span style=display:flex><span>The value of config<span style=color:#f92672>.</span>count <span style=color:#f92672>is</span> <span style=color:#ae81ff>5</span>
</span></span></code></pre></div><p>运行该命令将自动设置包信息（<code>__package__</code>变量）。现在，python 解释器可以成功解析 <code>project\ demos\demo.py</code> 中的相对引用了（甚至认为 <code>__name __</code> = <code>__ main__</code> ）。</p><p>[1] <strong>译者注：注意使用 <code>-m</code> 参数的时候，后面指定的执行文件没有 <code>.py</code> 后缀</strong></p><p>import-error-relative-no-parent</p><blockquote><p><strong>注：转载请保留下面的内容</strong></p><p>原文链接：<a href=https://www.napuzba.com/story/import-error-relative-no-parent/>https://www.napuzba.com/story/import-error-relative-no-parent/</a></p><p>译文链接：<a href=http://vimiix.com/post/2017/12/29/import-error-relative-no-parent/>http://vimiix.com/post/2017/12/29/import-error-relative-no-parent/</a></p></blockquote></div></article></main><aside><div><div><h3>LATEST POSTS</h3></div><div><ul><li><a href=/posts/2025-10-16-kubernetes-apiserver-authorization-mechanism/>Kubernetes APIServer 鉴权机制</a></li><li><a href=/posts/2025-09-30-kubernetes-apiserver-authentication-mechanism/>Kubernetes APIServer 认证机制</a></li><li><a href=/posts/2024-12-16-deploy-kubernetes-by-kubeadm/>使用 kubeadm 搭建 kubernetes 集群</a></li><li><a href=/posts/2024-09-20-how-to-code-review/>如何做code review</a></li><li><a href=/posts/2024-08-12-weakref-in-python/>Python中的弱引用</a></li></ul></div></div></aside><footer><p>Social Links:
<a href=https://github.com/vimiix><b>Github</b></a>.
<a href=https://www.douban.com/people/vimiix/><b>Douban</b></a>.
<a href=mailto:i@vimiix.com><b>Email</b></a>.<br><hr>&copy; 2017-2025
Vimiix Yao; All rights reserved.
<a href=https://beian.miit.gov.cn/>京ICP备19015214号-1</a></p><script src=https://l2dwidget.js.org/lib/L2Dwidget.min.js></script><script>L2Dwidget.init({model:{jsonPath:"https://unpkg.com/live2d-widget-model-tororo@1.0.5/assets/tororo.model.json"}})</script></footer></body></html>